package com.atguigu.common.utils;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;
import java.util.function.Supplier;

public class AsyncUtils {


    private static final Logger logger = LoggerFactory.getLogger(AsyncUtils.class);

    /**
     * cpu核心数
     */
    private static final int CPU_CORES = Runtime.getRuntime().availableProcessors();

    /**
     * 线程工厂
     */
    private static ThreadFactoryBuilder threadFactoryBuilder = new ThreadFactoryBuilder()
            .setNameFormat("app-web-pool-%d")
            .setDaemon(true);
    /**
     * 线程池
     */
    public static final Executor EXECUTOR = new ThreadPoolExecutor(CPU_CORES * 20, CPU_CORES * 30,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(4096), threadFactoryBuilder.build(), new ThreadPoolExecutor.AbortPolicy());

    /**
     * 异步执行，有返回值
     *
     * @param supplier
     * @param <U>
     * @return CompletableFuture<U>
     */
    public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) {
        return CompletableFuture.supplyAsync(supplier, EXECUTOR);
    }

    /**
     * 异步执行，没有返回值
     *
     * @param runnable
     */
    public static void runAsync(Runnable runnable) {
        CompletableFuture.runAsync(runnable, EXECUTOR).exceptionally(e -> {
            logger.error("runAsync error", e);
            return null;
        });
    }

    /**
     * 异步执行，没有返回值，但是返回CompletableFuture对象
     *
     * @param runnable
     */
    public static CompletableFuture supplyAsync2(Runnable runnable) {
        return
                CompletableFuture.runAsync(runnable, EXECUTOR).exceptionally(e -> {
                    logger.error("runAsync error", e);
                    return null;
                });
    }
}
